; ACL2 Arithmetic Nonnegative Integer Mod and Gcd book.
; Copyright (C) 1998  John R. Cowles, University of Wyoming

; This book is free software; you can redistribute it and/or modify
; it under the terms of the GNU General Public License as published by
; the Free Software Foundation; either version 2 of the License, or
; (at your option) any later version.

; This book is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
; GNU General Public License for more details.

; You should have received a copy of the GNU General Public License
; along with this book; if not, write to the Free Software
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

; Written by:
; John Cowles
; Department of Computer Science
; University of Wyoming
; Laramie, WY 82071-3682 U.S.A.

#| Summer 1997
     Last modified 30 June 1998

      Depends on the Arithmetic Equalities book
             and the Arithmetic Inequalities book.

   Disabled theorems:
     Divisor-<=
     Linear-combination-for-nonneg-int-gcd

This book is used to prove all the axioms in the
     Arithmetic Rationals book

   To certify in Arithmetic Book directory:

      (certify-book "mod-gcd")

|#

(in-package "ACL2")

(local (include-book "inequalities"))

;;;;;;;;;;;;;;;;;;;;
;; Nonneg-int-mod ;;
;;;;;;;;;;;;;;;;;;;;

(defun
  nonneg-int-mod ( n d )
  (declare (xargs :guard (and (integerp n)
			      (>= n 0)
			      (integerp d)
			      (< 0 d))))
  (if (zp d)
      (nfix n)
      (if (< (nfix n) d)
	  (nfix n)
	(nonneg-int-mod (- n d) d))))

(defthm
  Nonneg-int-mod-<-divisor
  (implies (and (integerp d)
		(< 0 d))
	   (< (nonneg-int-mod n d) d))
  :rule-classes :linear)

(defthm
  Nonneg-int-mod-nonnegative-integer-quotient
  (equal (+ (nonneg-int-mod n d)
	    (* (nfix d)(nonnegative-integer-quotient n d)))
	 (nfix n))
  :rule-classes ((:elim
		  :corollary
		  (implies (and 
			    (integerp n)
			    (integerp d)
			    (>= n 0)
			    (>= d 0))
			   (equal
			    (+ 
			     (nonneg-int-mod n d)
			     (* d 
				(nonnegative-integer-quotient n
							      d)))
			    n)))))

(defthm
  Nonneg-int-mod-0
  (equal (nonneg-int-mod 0 d) 0)
  :hints (("Goal"
	   :use (:instance
		 Nonneg-int-mod-nonnegative-integer-quotient
		 (n 0)))))

(local
 (defun
   induct-on-nonneg-int ( j )
   (if (zp j)
       t
       (induct-on-nonneg-int (- j 1)))))

(defthm
  Nonneg-int-mod-+-*
  (implies (and (integerp j)
		(integerp n)
		(integerp x)
		(>= x 0)
		(< x n)
		(>= j 0))
	   (equal (nonneg-int-mod (+ x (* j n)) n)
		  x))
     :hints (("Goal"
	      :induct (induct-on-nonneg-int j))))

(defthm
  Nonneg-int-mod-+-*-nonneg-int-mod
  (implies (and (integerp j)
		(integerp n)
		(integerp x)
		(>= j 0)
		(< 0 n)
		(>= x 0))
	   (equal (nonneg-int-mod (+ x (* j n)) n)
		  (nonneg-int-mod x n))))

(defthm
  Nonneg-int-mod-+-*-nonneg-int-mod-1
  (implies (and (integerp j)
		(integerp k)
		(integerp n)
		(integerp x)
		(>= j 0)
		(>= k 0)
		(< 0 n)
		(>= x 0)
		(equal (nonneg-int-mod k n) 0))
	   (equal (nonneg-int-mod (+ x (* j k)) n)
		  (nonneg-int-mod x n)))
    :hints (("Goal"
	     :in-theory (disable Nonneg-int-mod-+-*-nonneg-int-mod)
	     :use (:instance
		   Nonneg-int-mod-+-*-nonneg-int-mod
		   (j (* j (nonnegative-integer-quotient k n))))
	     )))

(defthm
  Divisor-nonnegative-integer-quotient
  (implies (equal (nonneg-int-mod n d) 0)
	   (equal (* (nfix d)
		     (nonnegative-integer-quotient n d)) 
		  (nfix n)))
  :rule-classes nil)

(defthm
  Left-nonneg-int-mod-*
  (implies (and (integerp j)
		(integerp n)
		(>= n 0))
	   (equal (nonneg-int-mod (* j n) n) 0))
  :hints (("Goal"
	   :induct (induct-on-nonneg-int j))))

(defthm
  Right-nonneg-int-mod-*
  (implies (and (integerp j)
		(integerp n)
		(>= n 0))
	   (equal (nonneg-int-mod (* n j) n) 0)))

(defthm
  Nonneg-int-mod-*-0
  (implies (and (integerp j)
		(integerp y)
		(>= j 0)
		(equal (nonneg-int-mod j n) 0))
	   (equal (nonneg-int-mod (* j y) n) 0))
  :hints (("Goal"
	   :in-theory (disable Right-nonneg-int-mod-*)
	   :use ((:instance
		  Right-nonneg-int-mod-*
		  (j (* y (nonnegative-integer-quotient j n)))))
	   )))

(defthm
  Nonneg-Int-mod-+-0
  (implies (and (integerp x)
		(>= x 0)
		(>= y 0)
		(equal (nonneg-int-mod x n) 0)
		(equal (nonneg-int-mod y n) 0))
	   (equal (nonneg-int-mod (+ x y) n) 0)))

(defthm
  Nonneg-Int-mod-minus-0
  (implies (and (integerp x)
		(integerp y)
		(>= y 0)
		(equal (nonneg-int-mod x n) 0)
		(equal (nonneg-int-mod y n) 0))
	   (equal (nonneg-int-mod (- x y) n) 0))
  :hints (("Goal"
	   :in-theory (disable Right-nonneg-int-mod-*)
	   :use (:instance
		 Right-nonneg-int-mod-*
		 (j (- (nonnegative-integer-quotient x n)
		       (nonnegative-integer-quotient y n)))))))

(defthm
  Linear-combination-nonneg-int-mod
  (implies (and (integerp a)
		(integerp b)
		(integerp x)
		(integerp y)
		(>= a 0)
		(>= b 0)
		(equal (nonneg-int-mod a n) 0)
		(equal (nonneg-int-mod b n) 0))
	   (equal (nonneg-int-mod (+ (* a x)(* b y)) n) 0))
  :hints (("Goal"
	   :in-theory (disable Nonneg-Int-mod-minus-0)
	   :use ((:instance 
		  Nonneg-Int-mod-minus-0
		  (x (* a x))
		  (y (* b (- y))))
		 (:instance
		  Nonneg-int-mod-*-0
		  (j b)
		  (y (- y)))
		 (:instance 
		  Nonneg-Int-mod-minus-0
		  (x (* b y))
		  (y (* a (- x))))
		 (:instance
		  Nonneg-int-mod-*-0
		  (j a)
		  (y (- x)))))))

(defthm
  Divisor-<=
  (implies (and (integerp n)
		(> n 0)
		(equal (nonneg-int-mod n d) 0))
	   (<= d n)))

(in-theory (disable Divisor-<=))

(defthm
  Nonneg-int-mod-1
  (equal (nonneg-int-mod n 1) 0))
	  
;;;;;;;;;;;;;;;;;;;;
;; Nonneg-int-gcd ;;
;;;;;;;;;;;;;;;;;;;;

(defun
  nonneg-int-gcd ( x y )
  (declare (xargs :guard (and (integerp x)
			      (>= x 0)
			      (integerp y)
			      (>= y 0))))
  (if (zp y)
      (nfix x)
      (nonneg-int-gcd y (nonneg-int-mod x y))))

(defthm
  Nonneg-int-gcd->-0
  (implies (or (and (integerp d)
		    (> d 0))
	       (and (integerp n)
		    (> n 0)))
	   (> (nonneg-int-gcd n d) 0))
  :rule-classes :type-prescription)

(defthm
    Nonneg-int-gcd-is-COMMON-divisor
    (and (equal (nonneg-int-mod x (nonneg-int-gcd x y))
		0)
	 (equal (nonneg-int-mod y (nonneg-int-gcd x y))
		0)))

(mutual-recursion
 (defun
     nonneg-int-gcd-multiplier1 ( x y )
     (declare (xargs :guard (and (integerp x)
				 (integerp y)
				 (>= x 0)
				 (>= y 0))))
     (if (zp y)
	 1
         (nonneg-int-gcd-multiplier2 y (nonneg-int-mod x y))))

  (defun
     nonneg-int-gcd-multiplier2 ( x y )
     (declare (xargs :guard (and (integerp x)
				 (integerp y)
				 (>= x 0)
				 (>= y 0))))
     (if (zp y)
	 0
         (+ (nonneg-int-gcd-multiplier1 y (nonneg-int-mod x y))
	    (- (* (nonneg-int-gcd-multiplier2 y 
					      (nonneg-int-mod x y))
		  (nonnegative-integer-quotient x y)))))))

(defthm
    Linear-combination-for-nonneg-int-gcd
    (equal (nonneg-int-gcd x y)
	   (+ (* (nfix x)
		 (nonneg-int-gcd-multiplier1 x y))
	      (* (nfix y) 
		 (nonneg-int-gcd-multiplier2 x y)))))

(in-theory (disable Linear-combination-for-nonneg-int-gcd))

(defthm
  Nonneg-int-gcd-is-LARGEST-common-divisor-mod
  (implies (and (equal (nonneg-int-mod x d) 0)
		(equal (nonneg-int-mod y d) 0))
	   (equal (nonneg-int-mod (nonneg-int-gcd x y) d)
		  0))
  :hints (("Goal"
	   :in-theory 
	   (enable Linear-combination-for-nonneg-int-gcd))))

(defthm
  Nonneg-int-gcd-is-LARGEST-common-divisor-<=
  (implies (and (or (and (integerp x)
			 (> x 0))
		    (and (integerp y)
			 (> y 0)))
		(equal (nonneg-int-mod x d) 0)
		(equal (nonneg-int-mod y d) 0))
	   (<= d (nonneg-int-gcd x y)))
  :hints (("Goal"
	   :in-theory (enable Divisor-<=))))

(defthm
  Nonnegative-integer-quotient-gcd
  (implies (and (integerp x)
		(integerp y)
		(>= x 0)
		(>= y 0))
	   (and (equal (* (nonneg-int-gcd x y)
			  (nonnegative-integer-quotient 
			   x 
			   (nonneg-int-gcd x y)))
		       x)
		(equal (* (nonneg-int-gcd x y)
			  (nonnegative-integer-quotient 
			   y 
			   (nonneg-int-gcd x y)))
		       y)))
  :hints (("Goal"
	   :use ((:instance 
		  Divisor-nonnegative-integer-quotient
		  (n x)
		  (d (nonneg-int-gcd x y)))
		 (:instance 
		  Divisor-nonnegative-integer-quotient
		  (n y)
		  (d (nonneg-int-gcd x y)))))))

(defthm
  Linear-combination-gcd=1
  (implies (and (integerp x)
		(equal (nonneg-int-gcd y z) 1))
	   (equal (+ (* x y (nonneg-int-gcd-multiplier1 y z))
		     (* x z (nonneg-int-gcd-multiplier2 y z)))
		  x)))

(defthm
  Divisor-of-product-divides-factor
  (implies (and (equal (nonneg-int-mod (* x y) z) 0)
		(equal (nonneg-int-gcd y z) 1)
		(integerp x)
		(integerp y)
		(>= x 0)
		(>= y 0))
	   (equal (nonneg-int-mod x z) 0))
  :rule-classes nil
  :hints (("Goal" 
	   :use ((:instance
		  Linear-combination-nonneg-int-mod
		  (a (* x y))
		  (b z)
		  (n z)
		  (x (nonneg-int-gcd-multiplier1 y z))
		  (y (* x (nonneg-int-gcd-multiplier2 y z))))))))

(defthm
  Nonneg-int-mod-abs-+-*
  (implies (and (integerp j)
		(integerp n)
		(integerp x)
		(<= 0 n))
	   (equal (nonneg-int-mod (abs (+ x (* j n)))
				  (nonneg-int-gcd (abs x) n))
		  0))
  :rule-classes ((:rewrite
		  :corollary
		  (implies (and (integerp j)
				(integerp n)
				(integerp x)
				(<= 0 n)
				(<= (+ x (* j n)) 0)
				(<= x 0))
			   (equal 
			    (nonneg-int-mod (+ (- x)(- (* j n)))
					    (nonneg-int-gcd (- x) 
							    n))
			    0))
		  :hints (("Goal"
			   :cases ((< (+ x (* j n)) 0)))))
		 (:rewrite
		  :corollary
		  (implies (and (integerp j)
				(integerp n)
				(integerp x)
				(<= 0 n)
				(<= 0 (+ x (* j n)))
				(<= x 0))
			   (equal 
			    (nonneg-int-mod (+ x (* j n))
					    (nonneg-int-gcd (- x)
							    n))
			    0)))
		 (:rewrite
		  :corollary
		  (implies (and (integerp j)
				(integerp n)
				(integerp x)
				(<= 0 n)
				(<= (+ x (* j n)) 0)
				(<= 0 x))
			   (equal 
			    (nonneg-int-mod (+ (- x) (- (* j n)))
					    (nonneg-int-gcd x n))
			    0)))
		 (:rewrite
		  :corollary
		  (implies (and (integerp j)
				(integerp n)
				(integerp x)
				(<= 0 n)
				(<= 0 (+ x (* j n)))
				(<= 0 x))
			   (equal 
			    (nonneg-int-mod (+ x (* j n))
					    (nonneg-int-gcd x n))
			    0))))
  :hints (("Subgoal 4"
	   :use (:instance
		 Linear-combination-nonneg-int-mod
		 (a (- x))
		 (b n)
		 (x 1)
		 (y (- j))
		 (n (nonneg-int-gcd (- x) n))))
	  ("Subgoal 3"
	   :use (:instance 
		 Linear-combination-nonneg-int-mod
		 (a (- x))
		 (b n)
		 (x -1)
		 (y j)
		 (n (nonneg-int-gcd (- x) n))))
	  ("Subgoal 2"
	   :use (:instance
		 Linear-combination-nonneg-int-mod
		 (a x)
		 (b n)
		 (x -1)
		 (y (- j))
		 (n (nonneg-int-gcd x n))))
	  ("Subgoal 1"
	   :use (:instance
		 linear-combination-nonneg-int-mod
		 (a x)
		 (b n)
		 (x 1)
		 (y j)
		 (n (nonneg-int-gcd x n))))))

(defthm
  Nonneg-int-gcd-abs->=
  (implies (and (integerp j)
		(integerp n)
		(integerp x)
		(< 0 n))
	   (>= (nonneg-int-gcd (abs (+ x (* j n))) n)
	       (nonneg-int-gcd (abs x) n)))
  :rule-classes nil)

(defthm
  Nonneg-int-mod-abs
  (implies (and (integerp j)
		(integerp n)
		(integerp x)
		(< 0 n))
	   (equal 
	    (nonneg-int-mod (abs x)
			    (nonneg-int-gcd (abs (+ x (* j n))) 
					    n))
	    0))
  :rule-classes ((:rewrite
		  :corollary
		  (implies (and (integerp j)
				(integerp n)
				(integerp x)
				(<= 0 n)
				(<= (+ x (* j n)) 0)
				(<= x 0))
			   (equal 
			    (nonneg-int-mod (- x)
					    (nonneg-int-gcd
					     (+ (- x)(- (* j n))) 
					     n))
			    0)))
		 (:rewrite
		  :corollary
		  (implies (and (integerp j)
				(integerp n)
				(integerp x)
				(< 0 n)
				(<= 0 (+ x (* j n)))
				(<= x 0))
			   (equal 
			    (nonneg-int-mod (- x)
					    (nonneg-int-gcd 
					     (+ x (* j n)) 
					     n))
			    0)))
		 (:rewrite
		  :corollary
		  (implies (and (integerp j)
				(integerp n)
				(integerp x)
				(< 0 n)
				(<= (+ x (* j n)) 0)
				(<= 0 x))
			   (equal 
			    (nonneg-int-mod x
					    (nonneg-int-gcd 
					     (+ (- x)(- (* j n)))
					     n))
			    0)))
		 (:rewrite
		  :corollary
		  (implies (and (integerp j)
				(integerp n)
				(integerp x)
				(< 0 n)
				(<= 0 (+ x (* j n)))
				(<= 0 x))
			   (equal 
			    (nonneg-int-mod x
					    (nonneg-int-gcd 
					     (+ x (* j n)) 
					     n))
			    0))))
  :hints (("Subgoal 4"
	   :use (:instance 
		 Linear-combination-nonneg-int-mod
		 (a (+ (- x)(- (* j n))))
		 (b n)
		 (x 1)
		 (y j)
		 (n (nonneg-int-gcd (+ (- x)(- (* j n))) n))))
	  ("Subgoal 3"
	   :use (:instance
		 Linear-combination-nonneg-int-mod
		 (a (+ (- x) (- (* j n))))
		 (b n)
		 (x -1)
		 (y (- j))
		 (n (nonneg-int-gcd (+ (- x) (- (* j n))) n))))
	  ("Subgoal 2"
	   :use (:instance 
		 Linear-combination-nonneg-int-mod
		 (a (+ x (* j n)))
		 (b n)
		 (x -1)
		 (y j)
		 (n (nonneg-int-gcd (+ x (* j n)) n))))
	  ("Subgoal 1"
	   :use (:instance
		 Linear-combination-nonneg-int-mod
		 (a (+ x (* j n)))
		 (b n)
		 (x 1)
		 (y (- j))
		 (n (nonneg-int-gcd (+ x (* j n)) n))))))

(defthm
  Nonneg-int-gcd-abs-<=
  (implies (and (integerp j)
		(integerp n)
		(integerp x)
		(< 0 n))
	   (<= (nonneg-int-gcd (abs (+ x (* j n))) n)
	       (nonneg-int-gcd (abs x) n)))
  :rule-classes nil)

(defthm
  Nonneg-int-gcd-abs
  (implies (and (integerp j)
		(integerp n)
		(integerp x)
		(< 0 n))
	   (equal (nonneg-int-gcd (abs (+ x (* j n))) n)
		  (nonneg-int-gcd (abs x) n)))
  :rule-classes ((:rewrite
		  :corollary
		  (implies (and (integerp j)
				(integerp n)
				(integerp x)
				(< 0 n)
				(<= (+ x (* j n)) 0)
				(<= x 0))
			   (equal 
			    (nonneg-int-gcd (+ (- x)(- (* j n))) n)
			    (nonneg-int-gcd (- x) n)))
		  :hints (("Goal"
			   :cases ((< (+ x (* j n)) 0)))))
		 (:rewrite
		  :corollary
		  (implies (and (integerp j)
				(integerp n)
				(integerp x)
				(< 0 n)
				(<= 0 (+ x (* j n)))
				(<= x 0))
			   (equal (nonneg-int-gcd (+ x (* j n)) n)
				  (nonneg-int-gcd (- x) n))))
		 (:rewrite
		  :corollary
		  (implies (and (integerp j)
				(integerp n)
				(integerp x)
				(< 0 n)
				(<= (+ x (* j n)) 0)
				(<= 0 x))
			   (equal 
			    (nonneg-int-gcd (+ (- x)(- (* j n))) n)
			    (nonneg-int-gcd x n))))
		 (:rewrite
		  :corollary
		  (implies (and (integerp j)
				(integerp n)
				(integerp x)
				(< 0 n)
				(<= 0 (+ x (* j n)))
				(<= 0 x))
			   (equal (nonneg-int-gcd (+ x (* j n)) n)
				  (nonneg-int-gcd x n)))))
  :hints (("Goal"
	 :in-theory (disable Nonneg-int-mod-abs-+-*
			     Nonneg-int-mod-abs)
	 :use (Nonneg-int-gcd-abs->=
	       Nonneg-int-gcd-abs-<=))))

(defthm
  Commutativity-of-nonneg-int-gcd
  (implies (and (integerp x)
		(integerp y)
		(>= x 0)
		(>= y 0))
	   (equal (nonneg-int-gcd x y)
		  (nonneg-int-gcd y x)))
  :hints (("Goal"
	   :cases ((< x y)(> x y)))))

(defthm
  Cross-product-factor
  (implies (and (equal (nonneg-int-gcd a b) 1)
		(equal (* a d)(* b c))
		(integerp a)
		(integerp b)
		(integerp c)
		(integerp d)
		(>= a 0)
		(>= b 0)
		(>= c 0)
		(>= d 0))
	   (and (equal (nonneg-int-mod c a) 0)
		(equal (nonneg-int-mod d b) 0)))
  :rule-classes nil
  :hints (("Goal"
	   :use ((:instance
		  Divisor-of-product-divides-factor
		  (x c)
		  (y b)
		  (z a))
		 (:instance
		  Divisor-of-product-divides-factor
		  (x d)
		  (y a)
		  (z b))))))

(defthm
  Nonneg-int-gcd-1-right
  (equal (nonneg-int-gcd x 1)
	 1))

(defthm
  Nonneg-int-gcd-1-left
  (implies (and (integerp x)
		(>= x 0))
 	   (equal (nonneg-int-gcd 1 x)
		  1))
  :rule-classes ((:rewrite
		  :corollary
		  (equal (nonneg-int-gcd 1 x)
			 1)))
  :hints (("Goal"
	   :in-theory (disable Nonneg-int-gcd-1-right )
	   :use Nonneg-int-gcd-1-right)))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Numerator and Denominator ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defthm
  Nonneg-int-gcd-numerator-denominator
  (equal (nonneg-int-gcd (abs (numerator x))
			 (denominator x))
	 1)
  :rule-classes ((:rewrite
		  :corollary
		  (implies (>= (numerator x) 0)
			   (equal (nonneg-int-gcd (denominator x)
						  (numerator x))
				  1)))
		 (:rewrite
		  :corollary
		  (implies (<= (numerator x) 0)
			   (equal (nonneg-int-gcd (denominator x)
						  (- 
						   (numerator x)))
				  1))))
  :hints (("Goal"
	   :use (:instance
		 lowest-terms
		 (n (nonneg-int-gcd (abs (numerator x))
				    (denominator x)))
		 (r (* (signum (numerator x))
		       (nonnegative-integer-quotient 
			(abs (numerator x))
			(nonneg-int-gcd (abs (numerator x))
					(denominator x)))))
		 (q (nonnegative-integer-quotient 
		     (denominator x) 
		     (nonneg-int-gcd (abs (numerator x))
				     (denominator x))))))))

(defthm
  Lowest-terms-nonneg-int-mod
  (implies (and (integerp n1)
		(integerp n2)
		(integerp d1)
		(integerp d2)
		(> d1 0)
		(> d2 0)
		(equal (nonneg-int-gcd (abs n1) d1)
		       1)
		(equal (* (/ d1) n1)
		       (* (/ d2) n2)))
	   (and (equal (nonneg-int-mod d2 d1) 0)
		(equal (nonneg-int-mod (abs n2)(abs n1)) 0)))
  :rule-classes nil
  :hints (("Goal"
	   :use (:instance
		 Cross-product-factor
		 (a (abs n1))
		 (b d1)
		 (c (abs n2))
		 (d d2)))))

(defthm
  Lowest-terms-<=
  (implies (and (integerp n1)
		(integerp n2)
		(integerp d1)
		(integerp d2)
		(> d1 0)
		(> d2 0)
		(equal (nonneg-int-gcd (abs n1) d1)
		       1)
		(equal (* (/ d1) n1)
		       (* (/ d2) n2)))
	   (and (<= d1 d2)
		(<= (abs n1)(abs n2))))
  :rule-classes nil
  :hints (("Goal"
	   :use Lowest-terms-nonneg-int-mod)))

(defthm
  LEAST-numerator-denominator-nonneg-int-mod
  (implies (and (integerp n)
		(integerp d)
		(> d 0))
	   (and (equal (nonneg-int-mod d 
				       (denominator (* (/ d) n)))
		       0)
		(equal (nonneg-int-mod (abs n)
				       (abs 
					(numerator (* (/ d) n))))
		       0)))
  :rule-classes ((:rewrite
		  :corollary
		  (implies (and (integerp n)
				(integerp d)
				(> d 0))
			   (equal 
			    (nonneg-int-mod d 
					    (denominator (* (/ d)
							    n)))
			    0)))
		 (:rewrite
		  :corollary
		  (implies (and (integerp n)
				(integerp d)
				(>= n 0)
				(> d 0))
			   (equal 
			    (nonneg-int-mod n 
					    (numerator (* (/ d)
							  n)))
			    0)))
		 (:rewrite
		  :corollary
		  (implies (and (integerp n)
				(integerp d)
				(<= n 0)
				(> d 0))
			   (equal 
			    (nonneg-int-mod (- n) 
					    (- 
					     (numerator (* (/ d)
							   n))))
			    0))))
  :hints (("Goal"
	   :use (:instance
		 Lowest-terms-nonneg-int-mod
		 (n1 (numerator  (* (/ d) n)))
		 (d1 (denominator (* (/ d) n)))
		 (n2 n)
		 (d2 d)))))

(defthm
  LEAST-numerator-denominator-<=
  (implies (and (integerp n)
		(integerp d)
		(> d 0))
	   (and (<= (denominator (* (/ d) n)) d)
		(<= (abs (numerator (* (/ d) n)))(abs n))))
  :rule-classes ((:linear
		  :corollary
		  (implies (and (integerp n)
				(integerp d)
				(> d 0))
			   (<= (denominator (* (/ d) n)) d)))
		 (:linear
		  :corollary
		  (implies (and (integerp n)
				(integerp d)
				(>= n 0)
				(> d 0))
			   (<= (numerator (* (/ d) n)) n)))
		 (:linear
		  :corollary
		  (implies (and (integerp n)
				(integerp d)
				(<= n 0)
				(> d 0))
			   (<= n (numerator (* (/ d) n))))))
  :hints (("Goal"
	   :in-theory (enable Divisor-<=))
	  ("Subgoal 1"
	   :cases ((> n 0)))))

(defthm
  Unique-rationalp
  (implies (and (integerp n)
		(integerp d)
		(> d 0)
		(equal (nonneg-int-gcd (abs n) d)
		       1))
	   (and (equal (denominator (* (/ d) n)) d)
		(equal (numerator (* (/ d) n)) n)))
  :hints (("Goal"
	   :use (:instance
		 Lowest-terms-<=
		 (n1 n)
		 (d1 d)
		 (n2 (numerator (* (/ d) n)))
		 (d2 (denominator (* (/ d) n)))))))

